//////////////////////////////////////////ok
#include"stdafx.h"
#include "bochs.h"



void IA32_CPU::PUSH_RX(Ia32_Instruction_c *i)
{
	push_16(  gen_reg[i->opcodeReg()].word.rx );
}

void IA32_CPU::POP_RX(Ia32_Instruction_c *i)
{
	Bit16u rx;
	pop_16(&rx);
	gen_reg[i->opcodeReg()].word.rx = rx;
}

void IA32_CPU::POP_Ew(Ia32_Instruction_c *i)
{
	Bit16u val16;
	pop_16(&val16);

	if (i->modC0()) 
	{
		IA32_WRITE_16BIT_REG(i->rm(), val16);
	}
	else 
	{
		if (i->as32L() && (!i->modC0()) && (i->rm()==4) && (i->sibBase()==4)) 
		{
			IA32_CPU_CALL_METHODR (i->ResolveModrm, (i));
		}
		write_virtual_word(i->seg(), IA32_RMAddr(i), &val16);
	}
}

void IA32_CPU::PUSHAD16(Ia32_Instruction_c *i)
{
	Bit32u temp_ESP;
	Bit16u sp;

	if ( sregs[IA32_SEG_REG_SS].cache.u.segment.d_b)
		temp_ESP = ESP;
	else
		temp_ESP = SP;

	if (!can_push(& sregs[IA32_SEG_REG_SS].cache, temp_ESP, 16) ) 
	{
		exception(IA32_SS_EXCEPTION, 0, 0);
		return;
	}

	sp = SP;
	push_16(AX);
	push_16(CX);
	push_16(DX);
	push_16(BX);
	push_16(sp);
	push_16(BP);
	push_16(SI);
	push_16(DI);
}

void IA32_CPU::POPAD16(Ia32_Instruction_c *i)
{
	Bit16u di, si, bp, tmp, bx, dx, cx, ax;
	if ( !can_pop(16) ) 
	{
		exception(IA32_SS_EXCEPTION, 0, 0);
		return;
	}

	pop_16(&di);
	pop_16(&si);
	pop_16(&bp);
	pop_16(&tmp); /* value for SP discarded */
	pop_16(&bx);
	pop_16(&dx);
	pop_16(&cx);
	pop_16(&ax);

	DI = di;
	SI = si;
	BP = bp;
	BX = bx;
	DX = dx;
	CX = cx;
	AX = ax;
}

void IA32_CPU::PUSH_Iw(Ia32_Instruction_c *i)
{
	push_16(i->Iw());
}

void IA32_CPU::PUSH_Ew(Ia32_Instruction_c *i)
{
	Bit16u op1_16;
	if (i->modC0()) 
	{
		op1_16 = IA32_READ_16BIT_REG(i->rm());
	}
	else 
	{
		read_virtual_word(i->seg(), IA32_RMAddr(i), &op1_16);
	}
	push_16(op1_16);
}
